﻿namespace Cavy.UdpClient
{
    public class UdpClient : MessageFactory
    {
        private Transport _transport;
        public Transport Transport { set; get; }
        
        private readonly uint _gameId;
        public event System.Action<IMessage> OnReceive;
        public event System.Action<Message_JoinRoomResponse> OnJoinRoomResponse;

        public UdpClient(uint gameId)
        {
            _gameId = gameId;
        }

        public void Dispose()
        {
            _transport.Dispose();
        }

        private void Listener()
        {
            Transport.OnReceived += result =>
            {
                IMessage resultData = Parse(_gameId, result.Buffer, result.RemoteEndPoint);
                if (resultData != null)
                {
                    switch ((MessageTypeEnum) resultData.MessageType)
                    {
                        case MessageTypeEnum.JoinRoomResponse:
                            OnJoinRoomResponse?.Invoke((Message_JoinRoomResponse) resultData);
                            break;
                        default:
                            OnReceive?.Invoke(resultData);
                            break;
                    }
                }
            };
            Transport.ReceiveAsync();
        }

        public void JoinRoom(string address, int port)
        {
            Transport.OnConnected -= OnConnected;
            Transport.OnConnected += OnConnected;
            Transport._Connect(address, port);
        }

        private void OnConnected()
        {
            Transport.Send(_gameId, new Message_JoinRoomRequest());
            Listener();
        }

        public void Send(IMessage message)
        {
            Transport.Send(_gameId, message);
        }

        internal void CallOnJoinRoomResponse(Message_JoinRoomResponse message)
        {
            OnJoinRoomResponse?.Invoke(message);
        }
    }
}